package com.tang.javaSwingCaculate.CaculateGUI;

import com.tang.javaSwingCaculate.Stack.InToPost;
import com.tang.javaSwingCaculate.Stack.OtherFunction;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import javax.swing.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.Map;
import java.util.Random;


/**
 * @author tmh
 * @date 2022/12/10 16:09
 * @description 计算器page
 */
@Slf4j
@Data
public class Calculate {

    public static void main(String args[]) {
        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame jf = new JFrame("calculator");
        jf.setSize(1080, 400);
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        jf.setLocationRelativeTo(null);

        Container c = jf.getContentPane();
        c.setLayout(new GridLayout(2, 1));

        JPanel jP = new JPanel(new GridLayout(6, 5));

        JButton[] jButtons = new JButton[30];
        /**
         * 设置logo
         */
        ImageIcon icon = new ImageIcon("D:\\java项目\\gitee\\calulate\\caculate_implement\\src\\main\\java\\com\\tang\\javaSwingCaculate\\CaculateGUI\\suyu.jpg");
        ImageIcon xk2 = new ImageIcon("D:\\java项目\\gitee\\calulate\\caculate_implement\\src\\main\\java\\com\\tang\\javaSwingCaculate\\CaculateGUI\\ck5.jpg");
        Image img = xk2.getImage();
        jf.setIconImage(icon.getImage());
        /*
         * 页面button--------------------------------start-------------------------------------------
         */
        jButtons[0] = new JButton("7");
        jButtons[1] = new JButton("8");
        jButtons[2] = new JButton("9");
        jButtons[3] = new JButton("(");
        jButtons[4] = new JButton(")");

        jButtons[5] = new JButton("4");
        jButtons[6] = new JButton("5");
        jButtons[7] = new JButton("6");
        jButtons[8] = new JButton("*");
        jButtons[9] = new JButton("/");

        jButtons[10] = new JButton("1");
        jButtons[11] = new JButton("2");
        jButtons[12] = new JButton("3");
        jButtons[13] = new JButton("+");
        jButtons[14] = new JButton("-");

        jButtons[15] = new JButton("COLOR");
        jButtons[16] = new JButton("0");
        jButtons[17] = new JButton(".");
        jButtons[18] = new JButton("BACK");
        jButtons[19] = new JButton("CLEAR");

        jButtons[20] = new JButton("%");
        jButtons[21] = new JButton("1/x");
        jButtons[22] = new JButton("x²");
        jButtons[23] = new JButton("√");
        jButtons[24] = new JButton("B");

        jButtons[25] = new JButton("x!");
        jButtons[26] = new JButton("PI");
        jButtons[27] = new JButton("YES");
        jButtons[28] = new JButton("e");
        jButtons[29] = new JButton("abs");
//-----------------------------------页面button----------------------------------end---------------------------------
        for (int i = 0; i < 30; i++) {
            //设置字体为宋体，大小为12号，粗体
            jButtons[i].setFont(new Font("宋体", Font.BOLD, 20));
            jButtons[i].setBackground(Color.PINK);
            jP.add(jButtons[i]);
        }


        JPanel jP2 = new JPanel(new FlowLayout()) {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawImage(img, 0, 0, this);
            }
        };


//-------------文本域对象JTextArea创建-------------------------
        JTextArea jTextArea = new JTextArea(7, 30);
        jTextArea.setFont(new Font("宋体", Font.BOLD, 20));
        jTextArea.setBackground(Color.orange);
//--------------设置自动换行----------------------------
        jTextArea.setLineWrap(true);
        /*
         * 计算器实体对象
         */
        InToPost inToPost = new InToPost(jTextArea.getText());

        JLabel label = new JLabel("welcome to use");
        label.setFont(new Font("宋体", Font.BOLD, 20));
        label.setOpaque(true);
        label.setBackground(Color.ORANGE);
        label.setForeground(new Color(0, 108, 255));

        //查看历史操作记录按钮------history----------
        JButton history = new JButton("history");
        history.setFont(new Font("宋体", Font.BOLD, 20));
        history.setBackground(Color.MAGENTA);
        jP2.add(label);

        jP2.add(jTextArea);
        jP2.add(history);

//---------------------------------监听器-------------------------------------------------------//
        /*
         * 设置按钮的事件监听器
         */
        for (int i = 0; i < 18; i++) {
            int j = i;
            jButtons[i].addActionListener(new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (j != 15) {
                        jTextArea.append(jButtons[j].getText());
                    }

                }
            });
        }

        /*
         * 回退-back监听器
         */
        jButtons[18].addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (jTextArea.getText().length() < 1) {
                    throw new RuntimeException("请输入有效值之后在回退");
                }
                jTextArea.setText(jTextArea.getText().substring(0, jTextArea.getText().length() - 1));
                System.out.println(jTextArea.getText());
            }
        });

        /*
         * clear 监听器
         */
        jButtons[19].addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                inToPost.getOpStack().clear();
                jTextArea.setText("");
            }
        });

        /*
         * 回车 YES监听器
         */

        jButtons[27].addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                inToPost.setInput(jTextArea.getText());//获取用户输入的表达式
                inToPost.formatTrans();//进行中序到后序的操作
                Double result = inToPost.calculateResult();//计算出结果
                jTextArea.setText("");//清空用户输入框

                if (result == null) {
                    log.error("用户并未输入任何值");
                } else {
                    if (result > Double.MAX_VALUE) {
                        log.info("数据过大----NAN----");
                    }
                    log.info(result.toString());//控制台打印结果
                    log.info("------------------------------------------");

                }

                jTextArea.append(String.valueOf(result));//把结果展示在控制台
                inToPost.getOpStack().clear();//存储中序的数组清空
                inToPost.getOutStack().clear();//存储后序的数组清空


            }
        });

        /**
         * 历史操作记录 history 监听器
         */
        history.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                jTextArea.setText("");
                for (Map.Entry<Integer, String> entry : InToPost.map.entrySet()) {
                    Integer key = entry.getKey();
                    String value = entry.getValue();
                    jTextArea.append("第" + key + "次的输入为" + value);
                    jTextArea.append("\r\n");
                    log.info("第" + key + "次的输入为" + value);
                }
            }
        });

        /**
         * 自定义输入框颜色 color 监听器
         */
        jButtons[15].addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Random random = new Random();
                jTextArea.setBackground(new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256)));
            }
        });


        /**
         * 求模运算 %
         */
        jButtons[20].addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                OtherFunction function = new OtherFunction();
                Double mod = function.getMod(jTextArea.getText());
                if (mod == null) {
                    jTextArea.setText("取模运算的格式为 a-b ,输入完成之后点击“%”");
                    log.info("用户取模运算输入有误");
                } else {
                    jTextArea.setText(String.valueOf(mod));
                    log.info("取模运算的结果为" + mod);
                    InToPost.map.put(++InToPost.OPERATE_COUNT, jTextArea.getText());
                }
            }
        });
        /**
         * 倒数监听器 1/x
         */
        jButtons[21].addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                OtherFunction function = new OtherFunction();
                Double reciprocal = function.getReciprocal(jTextArea.getText());
                if (reciprocal == null) {
                    jTextArea.setText("");
                    jTextArea.setText("输入有误，请调整后充实");
                    log.info("---用户输入有误在调用getReciprocal（）方法时候---");
                } else {
                    jTextArea.setText("");
                    jTextArea.setText(String.valueOf(reciprocal));
                    InToPost.map.put(++InToPost.OPERATE_COUNT, jTextArea.getText());
                }
            }
        });

        /**
         * 平方数监听器 x的平方
         */
        jButtons[22].addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                OtherFunction function = new OtherFunction();
                Double square = function.getSquare(jTextArea.getText());
                if (square == null) {
                    jTextArea.setText("");
                    jTextArea.setText("输入有误，请调整后充实");
                    log.info("---用户输入有误在调用getReciprocal（）方法时候---");
                } else {
                    jTextArea.setText("");
                    jTextArea.setText(String.valueOf(square));
                    InToPost.map.put(++InToPost.OPERATE_COUNT, jTextArea.getText());
                    log.info(String.valueOf(square));
                }
            }
        });

        /**
         * 根号监听器 根号
         */
        jButtons[23].addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                OtherFunction function = new OtherFunction();
                Double radical = function.getRadical(jTextArea.getText());
                if (radical == null) {
                    jTextArea.setText("");
                    jTextArea.setText("输入有误，请调整后充实");
                    log.info("---用户输入有误在调用getReciprocal（）方法时候---");
                } else {
                    jTextArea.setText("");
                    jTextArea.setText(String.valueOf(radical));
                    log.info(String.valueOf(radical));
                    InToPost.map.put(++InToPost.OPERATE_COUNT, jTextArea.getText());
                }
            }
        });

        /**
         * 二进制监听器 B
         */
        jButtons[24].addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                OtherFunction function = new OtherFunction();
                Double b = function.getB(jTextArea.getText());
                if (b == null) {
                    jTextArea.setText("");
                    jTextArea.setText("输入有误，请调整后充实");
                    log.info("---用户输入有误在调用getReciprocal（）方法时候---");
                } else {
                    jTextArea.setText("");
                    jTextArea.setText(String.valueOf(b));
                    log.info(String.valueOf(b));
                    InToPost.map.put(++InToPost.OPERATE_COUNT, jTextArea.getText());
                }
            }
        });

        /**
         * 阶乘监听器 x!
         */
        jButtons[25].addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                OtherFunction function = new OtherFunction();
                Double factorial = function.getFactorial(jTextArea.getText());
                if (factorial == null) {
                    jTextArea.setText("");
                    jTextArea.setText("输入有误，请调整后充实");
                    log.info("---用户输入有误在调用getReciprocal（）方法时候---");
                } else {
                    jTextArea.setText("");
                    jTextArea.setText(String.valueOf(factorial));
                    log.info(String.valueOf(factorial));
                    InToPost.map.put(++InToPost.OPERATE_COUNT, jTextArea.getText());
                }
            }
        });

        /**
         * PI 监听器
         */
        jButtons[26].addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                OtherFunction function = new OtherFunction();
                jTextArea.setText("");
                jTextArea.setText(String.valueOf(function.getP()));
                InToPost.map.put(++InToPost.OPERATE_COUNT, "PI");
            }
        });

        /**
         * e 监听器
         */
        jButtons[28].addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                OtherFunction function = new OtherFunction();
                jTextArea.setText("");
                jTextArea.setText(String.valueOf(function.getE()));
                InToPost.map.put(++InToPost.OPERATE_COUNT, "e");
            }
        });
        /**
         * abs 绝对值监听器
         */
        jButtons[29].addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                OtherFunction function = new OtherFunction();
                Double abs = function.getAbs(jTextArea.getText());
                if (abs == null) {
                    jTextArea.setText("");
                    jTextArea.setText("输入有误，请调整后充实");
                    log.info("---用户输入有误在调用getReciprocal（）方法时候---");
                } else {
                    jTextArea.setText(String.valueOf(abs));
                    log.info(String.valueOf(abs));
                    InToPost.map.put(++InToPost.OPERATE_COUNT, jTextArea.getText());
                }
            }
        });

        c.add(jP2);
        c.add(jP);

        jf.setVisible(true);
    }
}
